#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <stdbool.h>
#define MaxSize 1000
typedef struct Student
{
	int Id;
	char Name[15];
	int age;
}ElemType;
typedef struct SlinkNode
{
	ElemType date;
	struct SlinkNode* next;
}Lnode, * LinkList;

//Lnode用于单个的.链表对象的创建等操作
//*LinkList是整个链表一般是链表的表头
/*void Initial()
{
	LinkList L;//这里的L就是创建一个L的链表进行初始化
	L = (Lnode*)malloc(sizeof(Lnode));//对L链表进行初始化空间创建
	L->next = NULL;		//对表头的next节点作为空指针!!!!!!!!!!!!!错误
}*/
LinkList Initial()
{
	LinkList L = (Lnode*)malloc(sizeof(Lnode));
	if (L != NULL) { // 总是检查 malloc 的返回值
		L->next = NULL;
	}
	return L; // 返回这个新创建的头结点
}
int Insert(LinkList L,int i ,ElemType e)//i是插入位置，e是插入的值
{
	Lnode * p=L;//p为L链表的头结点就是第一个没有数据内容的单纯的第一个节点故以后例如第三个节点那么就要i+1也就是4
	int j = 0;//j为计数器来控制指针p的向后移动找到插入位置
	while (p != NULL && j < i - 1)//p指针不能到空指针位置，j是计数器控制p的移动找到插入位置i的前驱节点
	{
		p = p->next;
		j++;
	}
	if (p==NULL)
	{
		return 0;
	}
	Lnode* s = (Lnode*)malloc(sizeof(Lnode));//为新的数据节点s创建一个Lnode大小的空间
	s->date = e;
	s->next = p->next;//现将s链接到原来p的下一个即下面的20位置
	p->next = s;//s的头再给p的next把s的头插入到原来前驱节点的尾巴后
	/*初始状态：
		L(头节点) →[date] →[10] →[20] → NULL
		p = 这里    j = 0

		循环后（找到前驱）：
		L(头节点) →[date] →[10] →[20] → NULL
							 p = 这里   j = 1（i - 1 = 1）

		创建新节点s：
		s →[e] → ?

		插入后：
		L(头节点) →[date] →[10] →[e] →[20] → NULL
					p      s
	*/
	return 1;
}
bool HeadInsert(LinkList L, ElemType e)//进行头插，头插类似栈的操作类似先进后出逆序存放
{
	Lnode* p = L;
	if (p ==NULL)
		return false;
	//
	Lnode* s = (Lnode*)malloc(sizeof(Lnode));//开辟新的内存
	s->date = e;
	s->next = p->next;//类似按位插入，先对新的元素链接到下一个，再让头结点连接到新节点
	p->next = s;
	return true;
}
bool displayslink(LinkList L)
{
	Lnode* p = L->next;//头结点不存储数据date没数据要下一个节点
	if (p == NULL) {
		printf("暂无此学籍\n");
		return false;
	}
		printf("---------学籍信息如下------------\n");
	while (p != NULL)
	{
		printf("学号：%d\t姓名：%s\t年龄 %d\t\n",p->date.Id,p->date.Name,p->date.age);
		p = p->next;
	}
	return true;
}
/*Lnode* ValueLocate(LinkList L, ElemType e)//在链表L里面查找e返回节点指针p
{
	Lnode* p = L->next;
	while (p != NULL && p->date != e)
	{
		p = p->next;
	}
	return p;
}
*/
Lnode* WhereLocate(LinkList L, int i)
{
	Lnode* p = L;
	int j = 0;
	if (i < 1)
	{
		return NULL;
	}
	while (p != NULL && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}
int DelNodeW(LinkList L, int i)//删除位置i的节点p
{
	if (i < 1)
		return 0;
	Lnode* pre = L;
	int j = 0;
	while (pre != NULL && j < i - 1)
	{
		pre = pre->next;
		j++;
	}
	if (pre == NULL || pre->next == NULL)return 0;
	Lnode* p = pre->next;
	Lnode* next = p->next;
	pre->next = next;
	free(p);
	return 1;
}
Lnode* FindId(LinkList L,int Id)
{
	Lnode* p = L->next;
	if (p == NULL)
	{
		return NULL;
	}
	while (p != NULL&&p->date.Id !=Id )
	{
		p = p->next;
	}
	return p;
}
Lnode* FindName(LinkList L, char str[15])
{
	Lnode* p = L->next;
	while (p != NULL && strcmp(str, p->date.Name))
	{
		p = p->next;
	}
	return p;
}
int GetLength(LinkList L) {
	int count = 0;
	Lnode* p = L->next;
	while (p != NULL)
	{
		count++;
		p = p->next;
	}
	return count;
}
bool DelNodeByID(LinkList L, int Id) {
	Lnode* pre = L;
	Lnode* p = pre->next;
	while (p != NULL && p->date.Id != Id)
	{
		pre=p;
		p = p->next;
	}
	if (p==NULL)
	{
		return false;
	}
	Lnode* next = p->next;
	pre->next = next;
	free(p);
	return true;
}
void DestroyList(LinkList L) {
	Lnode* current;
	Lnode* nextnode;
	current = L;
	while (current != NULL)
	{
		nextnode = current->next;
		free(current);
		current = nextnode;
	}
	L = NULL;
}

// 清空输入缓冲区
void clear_input_buffer() {
	int c;
	while ((c = getchar()) != '\n' && c != EOF);
}

// 按学号修改学生信息
bool UpdateStudentByID(LinkList L, int Id) {
	Lnode* p = FindId(L, Id);
	if (p == NULL) {
		return false;
	}
	
	printf("找到学号 %d 的学生：\n", Id);
	printf("当前信息 - 姓名：%s, 年龄：%d\n", p->date.Name, p->date.age);
	printf("请输入新的姓名：");
	scanf("%14s", p->date.Name);
	clear_input_buffer();
	
	printf("请输入新的年龄：");
	scanf("%d", &p->date.age);
	clear_input_buffer();
	
	return true;
}